package com.nsn.vs.sdm.util.resources;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.Map.Entry;

/**
 * The utility of resources
 * 
 * @author Jeccy.Zhao
 *
 */
public class UtilResources 
{
	/**
	 * Instance of JAR utility
	 */
	public static UtilJar ju = new UtilJar(UtilResources.class);
	
	/**
	 * Base path
	 */
	public static String basePath = ju.getJarPath();
	
	/**
	 * prefix of file resource
	 */
	public static final String RESOURCE_FILE_PREFIX = System.getProperty("os.name")
			.toUpperCase().indexOf("WINDOWS") > -1 ? "file:/" : "file:";
	
	/**
	 * prefix of classpath resource
	 */
	public static final String RESOURCE_CLASSPATH_PREFIX = "classpath:";
	
	/**
	 * Returns the web class path
	 * 
	 * @return web class path
	 */
	public static String getClassPath()
	{
		String classPath = UtilResources.class.getResource("/").toString();
		if(classPath.indexOf(RESOURCE_FILE_PREFIX) > -1)
		{
			classPath = classPath.substring(RESOURCE_FILE_PREFIX.length());
		}
		return classPath;
	}
	
	/**
	 * Returns the  root path
	 * 
	 * @return  root path
	 */
	public static String getRootPath()
	{
		return basePath;
	}
	
	/**
	 * Returns the properties from the property file
	 * 
	 * @param propFilePath  
	 *          the property file path, format can be classpath:xxxx, etc.
	 * @return the properties laid in a hash-map
	 */
	public static Map<String, String> getProperties(String propFile)
	{
		Properties props = new Properties();
		InputStream stream = null;
		try 
		{
			if(propFile.indexOf(RESOURCE_CLASSPATH_PREFIX) > -1)
			{
				propFile = propFile.replaceFirst(RESOURCE_CLASSPATH_PREFIX, UtilResources.getClassPath()); 
			}
			stream = new FileInputStream(new File(propFile));
			props.load(stream);
			Map<String, String> propMaps = new HashMap<String, String>();
			for(Entry<Object, Object> entry : props.entrySet())
			{
				if(entry.getKey() != null)
				{
					propMaps.put(entry.getKey().toString(), entry.getValue().toString());
				}
			}
			return propMaps;
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		} 
		finally 
		{
			if(stream != null)
			{
				try 
				{
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	/**
	 * 
	 * @return
	 * @author Zhao.Xiang
	 */
	public static String getPhyResourcePath() 
	{
		String tmp = UtilResources.class.getResource("/").getFile();
		return tmp.substring(1, tmp.length() - 1);
	}
	
	/**
	 * 
	 * @return
	 * @author Zhao.Xiang
	 */
	public static String getPhyBasePath() 
	{
		String path = getPhyResourcePath();
		return path.substring(0, path.lastIndexOf("/"));
	}
	
	/**
	 * Obtains parameter from the property configuration file
	 * 
	 * @param propFile
	 * @return
	 */
	public static TreeMap<String, String> getParamsFromPropConfig(
			String propFile) throws IOException 
	{
		File file = new File(propFile);
		if(!file.exists())
		{
			return null;
		}
		
		Properties prop = new Properties();
		TreeMap<String, String> params = new TreeMap<String, String>();
		
		prop.load(new InputStreamReader(new FileInputStream(file)));

		for (Iterator<Object> it = prop.keySet().iterator(); it.hasNext();) 
		{
			String key = (String) it.next();
			params.put(key, prop.get(key).toString().trim());
		}
		
		return params;
	}
	
	
	/**
	 * Writes properties on property file
	 * 
	 * @param propFile
	 * @param params
	 * @return
	 */
	public static boolean writeProperties(String propFile,
			Map <String,String> params) throws Exception 
	{
		Properties prop = new Properties();
		
		prop.load(new FileInputStream(propFile));
		OutputStream fos = new FileOutputStream(propFile);
		
		for(Map.Entry<String, String> entry : params.entrySet())
		{
			prop.setProperty(entry.getKey(), entry.getValue());
		}
		
		prop.store(fos, "Update on " + new Date().toString());
		
		return true;
	}
	
	/**
	 * Writes the specified property to configuration file
	 * 
	 * @param propFile
	 * @param keyName
	 * @param keyValue
	 */
	public static void writeProperties(String propFile,
			String keyName,String keyValue) throws Exception
	{
		Properties prop = new Properties();

		prop.load(new FileInputStream(propFile));
		OutputStream fos = new FileOutputStream(propFile);
		prop.setProperty(keyName, keyValue);
		prop.store(fos, "Update '" + keyName + "' value");
	}
	
	public static void main(String[] args)
	{
		System.out.println(UtilResources.getClassPath());
		System.out.println(UtilResources.getRootPath());
		System.out.println(UtilResources.getPhyBasePath());
	}
	
}
